package api.action;

import api.model.ApiColumn;
import api.model.ApiTable;
import api.service.ApiColumnService;
import m.common.action.ActionMeta;
import m.common.action.RequestMeta;
import m.common.action.VuePageResult;
import m.common.action.VueResult;
import m.common.model.FieldMeta;
import m.common.model.LinkTableMeta;
import m.common.model.Model;
import m.common.model.TableMeta;
import m.common.model.config.ModelConfig;
import m.common.model.type.FieldType;
import m.common.model.util.ModelQueryList;
import m.common.model.util.QueryCondition;
import m.common.model.util.QueryOrder;
import m.html.VueListResult;
import m.html.element.attr.Align;
import m.html.element.attr.ButtonType;
import m.html.element.other.ItemsQuery;
import m.html.list.*;
import m.system.exception.MException;
import m.system.util.ClassUtil;
import m.system.util.JSONMessage;
import m.system.util.StringUtil;
import manage.action.ManageAction;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@ActionMeta(name="api/apiColumn")
public class ApiColumnAction extends ManageAction {
    private ApiColumn model;

    public JSONMessage doSave(){
        JSONMessage result=new JSONMessage();
        try {
            verifyAdminOperPower("manage_api_power");
            String msg=getService(ApiColumnService.class).save(model);
            fillJSONResult(result,true,msg);
        } catch (Exception e) {
            fillJSONResult(result,false,e);
        }
        return result;
    }
    public JSONMessage doDelete(){
        JSONMessage result=new JSONMessage();
        try {
            verifyAdminOperPower("manage_api_power");
            String msg=getService(ApiColumnService.class).delete(model);
            fillJSONResult(result,true,msg);
        } catch (Exception e) {
            fillJSONResult(result,false,e);
        }
        return result;
    }
    public VueResult toEdit() throws Exception {
        verifyAdminOperPower("manage_api_power");
        if(null!=model&&!StringUtil.isSpace(model.getOid())){
            model= ModelQueryList.getModel(model,"*");
        }else if(null!=model&&!StringUtil.isSpace(model.getTable().getOid())){
            model.setNotnull("N");
            model.setIsinit("N");
        }else{
            throw new MException(this.getClass(),"参数错误");
        }
        List<Class<? extends Model>> classList=ModelConfig.getTableList();
        List<JSONMessage> modelClasses= new ArrayList<>();
        for(Class<? extends Model> clazz : classList){
            TableMeta tm=ModelConfig.getTableMeta(clazz);
            JSONMessage data=new JSONMessage();
            data.push("key", clazz.getName());
            data.push("value", clazz.getName());
            boolean isSys= clazz.getName().contains("manage.model") || clazz.getName().contains("flow.model")
                || clazz.getName().contains("api.model");
            data.push("label", (isSys?"[系统] ":"")+tm.description()+" "+tm.name());
            modelClasses.add(data);
        }
        return new VuePageResult("page/base/api/editApiColumn.js")
            .addParam("model",model)
            .addParam("modelClasses",modelClasses)
            .addParam("modelTables",
                new ItemsQuery(ApiTable.class,"name","oid")
                    .setTitleExpression("concat(#{name},' - ',ifnull(#{description},''))")
                    .addCond(QueryCondition.eq("isinit","Y"))
                    .toDatas()
            );
    }
    @RequestMeta(params = {"tableOid"})
    public JSONMessage getModelColumnOption(String tableOid){
        JSONMessage result=new JSONMessage();
        try {
            verifyAdminOperPower("manage_api_power");
            result.push("options",
                new ItemsQuery(ApiColumn.class,"description","name")
                    .setTitleExpression("concat(#{name},' - ',ifnull(#{description},''))")
                    .addCond(QueryCondition.eq("table.oid",tableOid))
                    .addCond(QueryCondition.notEmpty("modelTable.oid"))
                    .toDatas()
            );
            fillJSONResult(result,true,"");
        } catch (Exception e) {
            fillJSONResult(result,false,e);
        }
        return result;
    }
    @RequestMeta(params = {"tableClass"})
    public JSONMessage getTableMetaColumn(String tableClass){
        JSONMessage result=new JSONMessage();
        try {
            verifyAdminOperPower("manage_api_power");
            Class<? extends Model> clazz= ClassUtil.getClass(Model.class,tableClass);
            List<JSONMessage> list= new ArrayList<>();
            JSONMessage ob=new JSONMessage();
            ob.push("name","oid");
            ob.push("desc","主键");
            ob.push("type", FieldType.STRING);
            ob.push("length",50);
            ob.push("notnull",true);
            list.add(ob);
            Map<String, FieldMeta> fms=ModelConfig.getFieldMetaMap(clazz);
            for(FieldMeta fm : fms.values()){
                JSONMessage obj=new JSONMessage();
                obj.push("name",fm.name());
                obj.push("desc",fm.description());
                obj.push("type",fm.type());
                obj.push("length",fm.length());
                obj.push("notnull",fm.notnull());
                obj.push("defaultValue",fm.defaultValue());
                list.add(obj);
            }
            Map<String, LinkTableMeta> lts=ModelConfig.getLinkTableMetaMap(clazz);
            for(LinkTableMeta lt : lts.values()){
                JSONMessage obj=new JSONMessage();
                obj.push("name",lt.name());
                obj.push("desc",lt.description());
                obj.push("class",lt.table().getName());
                obj.push("notnull",lt.notnull());
                list.add(obj);
            }
            result.push("list",list);
            fillJSONResult(result,true,"");
        } catch (Exception e) {
            fillJSONResult(result,false,e);
        }
        return result;
    }
    public VueResult apiColumnList() throws Exception{
        setOrder(QueryOrder.asc("oid"));
        boolean isEdit= getParamsValue("oper").equals("edit");
        boolean power=hasAdminOperPower("manage_api_power");
        VueListResult result=getVueListResult("数据列列表", ApiColumn.class,"action/api/apiColumn/apiColumnList");
        result.setSubTitle("添加或者编辑数据列信息。");
        result.addCol(toIndexColumn());
        result.addCol(toTextColumn("字段", "name",true));
        result.addCol(toTextColumn("描述", "description",200,true));
        result.addCol(toTextColumn("类型", "type",true));
        result.addCol(toTextColumn("长度", "length",60,true));
        result.addCol(toTextColumn("非空", "notnull",60,true).addDisItem("Y","是","N","否"));
        result.addCol(toTextColumn("初始化", "isinit",60,true).addDisItem("Y","是","N","否"));
        if(power&&isEdit) result.addCol(toSpaceColumn("操作",130,
            ListElement.test("record.isinit!='Y'",
                ListButton.modal("修改", ButtonType.PRIMARY,"action/api/apiColumn/toEdit",800, SuccessMethod.REFRESH)
                    .addParam("model.oid","oid")
            ),
            ListElement.test("record.isinit!='Y'",
                ListButton.ajax("删除", ButtonType.WARN,"action/api/apiColumn/doDelete", SuccessMethod.REFRESH)
                    .addParam("model.oid","oid").setConfirm("确定要删除该字段吗?")
            )
        ).setFixed(Align.RIGHT));
        if(power&&isEdit) result.addButton(
            ListButton.modal("新增",ButtonType.PRIMARY,"action/api/apiColumn/toEdit",800,SuccessMethod.REFRESH)
                .addQueryParam("model.table.oid","table.oid")
        );
        result.addSearch(ListSearch.field("","table.oid", SearchType.HIDDEN_EQ));
        return result;
    }
    public ApiColumn getModel() {
        return model;
    }


    public void setModel(ApiColumn model) {
        this.model = model;
    }
}
